#ifndef __PLATFORMAUDIORESOURCE_INCLUDED
#define __PLATFORMAUDIORESOURCE_INCLUDED

namespace Audio
{	
	class ILocker
	{
	public:
		virtual ~ILocker(){}
		virtual void Lock() = 0;
		virtual void Unlock() = 0;
	};
	
	class IRunable
	{
	public:
		virtual ~IRunable(){}
		virtual void Run() = 0;
		virtual UINT32 ReturnCode() = 0;
	};


	class IThread
	{
	public:		
		
		virtual ~IThread(){}	
		virtual void Start(IRunable* runable) = 0;
		virtual void Join() = 0;
		virtual void Stop() = 0;
		virtual BOOL HasStopRequest() = 0;
	
		
	};

	class IEvent
	{
	public:
		virtual ~IEvent(){};
		virtual void Signal() = 0;
		virtual void WaitOn() = 0;
	};

	class IVoice : public ErroableObject
	{
	public:
		virtual ~IVoice(){};

		virtual void Start() = 0;
		virtual void Stop() = 0;
		virtual void SubmitData(UINT8* raw, UINT32 size, SubmitBufferType bufferType) = 0;
		
		virtual void SetUserData(void* pv) = 0;
		virtual void* GetUserData() = 0;

		virtual float GetVolume() = 0;
		virtual void  SetVolume(FLOAT vol) = 0;
	};
	
	
	class IAudioDeviceCallBack
	{
	public:
		virtual ~IAudioDeviceCallBack(){}
		virtual void OnNeedMoreData(void* context) = 0;		
		virtual void OnStreamEnd(void* context) = 0;
		virtual void OnVoiceError(void* context) = 0;
	};	
	


	class IAudioDevice : public ErroableObject
	{
	public:
		virtual ~IAudioDevice(){}
		virtual void Init() = 0;
		virtual void Destroy() = 0;

		virtual IVoice* CreateVoice(void* info, UINT32 infoSize) = 0;
		virtual void DestroyVoice(IVoice*& voice) = 0;

		virtual void SetDeviceCallback(IAudioDeviceCallBack* callback) = 0;
		virtual IAudioDeviceCallBack* GetDeviceCallback() = 0;

	};

	class IFactory
	{
	public:
		
		virtual ~IFactory(){}
		virtual IAudioDevice* CreateAudioDevice() = 0;
		virtual void DestroyAudioDevice(IAudioDevice*& device) = 0;

		virtual ILocker* CreateLocker() = 0;
		virtual void DestroyLocker(ILocker*& locker) = 0;

		virtual IThread* CreateThread() = 0;
		virtual void DestroyThread(IThread*& t) = 0;

		virtual IEvent* CreateEventObject() = 0;
		virtual void DestroyEventObject(IEvent*& e) = 0;
	};
}

#endif
